package com.cwf.metadatamanage.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.cwf.metadatamanage.exception.NotFoundException;
import com.cwf.metadatamanage.exception.ServerException;
import com.cwf.metadatamanage.exception.SourceException;
import com.cwf.metadatamanage.mapper.ColumnMapper;
import com.cwf.metadatamanage.mapper.TableMapper;
import com.cwf.metadatamanage.model.dtos.ColumnDto;
import com.cwf.metadatamanage.model.dtos.DBTables;
import com.cwf.metadatamanage.model.dtos.TableInfo;
import com.cwf.metadatamanage.model.pojo.Column;
import com.cwf.metadatamanage.model.pojo.Source;
import com.cwf.metadatamanage.model.pojo.Table;
import com.cwf.metadatamanage.model.vo.req.MetadataCollectReq;
import com.cwf.metadatamanage.service.MetadataCollectService;
import com.cwf.metadatamanage.service.SourceService;
import com.cwf.metadatamanage.utils.SqlUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service("metadataCollectService")
public class MetadataCollectServiceImpl implements MetadataCollectService {

    @Autowired
    private SourceService sourceService;

    @Resource
    private SqlUtils sqlUtils;

    @Autowired
    private TableMapper tableMapper;

    @Autowired
    private ColumnMapper columnMapper;

    /**
     * 获取Source的db
     *
     * @param id
     * @return
     * @throws NotFoundException
     * @throws ServerException
     */
    @Override
    public List<String> getSourceDatabases(Long id) throws NotFoundException, ServerException {
        Source source = sourceService.getSource(id);

        List<String> dbList = null;

        try {
            dbList = sqlUtils.init(source).getDatabases();
        } catch (SourceException e) {
            throw new ServerException(e.getMessage());
        }

        return dbList;
    }

    /**
     * 获取Source的data tables
     *
     * @param id
     * @return
     */
    @Override
    public DBTables getDatabaseTables(Long id, String dbName) throws NotFoundException {

        DBTables dbTable = new DBTables(dbName);
        Source source = sourceService.getSource(id);

        List<TableInfo> tableList = null;
        try {
            tableList = sqlUtils.init(source).getTableList(dbName);
        } catch (SourceException e) {
            throw new ServerException(e.getMessage());
        }

        if (CollectionUtils.isNotEmpty(tableList)) {
            dbTable.setTables(tableList);
        }

        return dbTable;
    }

    /**
     * 获取Source的data tables
     *
     * @param id
     * @param dbName
     * @param tableName
     * @return
     */
    @Override
    public TableInfo getTableInfo(Long id, String dbName, String tableName) throws NotFoundException {
        Source source = sourceService.getSource(id);

        TableInfo tableInfo = null;
        try {
            tableInfo = sqlUtils.init(source).getTableInfo(dbName, tableName);
        } catch (SourceException e) {
            throw new ServerException(e.getMessage());
        }

        return tableInfo;
    }

    @Override
    public boolean metadataCollectBySource(MetadataCollectReq metadataCollectReq) throws SourceException, NotFoundException {
        List<Table> allTableList = new ArrayList<>();
        List<Column> allColumnList = new ArrayList<>();


        // 1 获取对应的源
        Source source = sourceService.getSource(metadataCollectReq.getSourceId());

        // 2 获取源下面的所有库
        List<String> databaseNameList = sqlUtils.init(source).getDatabases();

        // 3 遍历数据源下的所有库,获取所有的表
        for (String databaseName : databaseNameList) {

            List<TableInfo> tableInfoList = sqlUtils.init(source).getTableList(databaseName);
            for (TableInfo tableInfo : tableInfoList) {
                List<Column> columnList = new ArrayList<>();
                Table table = new Table();
                table.setTableName(tableInfo.getTableName());
                table.setTableDescription(tableInfo.getTableDescription());
                table.setSourceId(source.getId());
                table.setSourceName(source.getName());
                table.setDatabaseName(databaseName);
                table.setCreateBy(source.getCreateBy());
                table.setCreateTime(LocalDateTime.now());
                allTableList.add(table);

                tableMapper.insert(table);

                TableInfo tableInfo1 = sqlUtils.init(source).getTableInfo(databaseName, tableInfo.getTableName());
                List<ColumnDto> columnDtoList = tableInfo1.getColumns();
                for (ColumnDto columnDto : columnDtoList) {
                    Column column = new Column();
                    BeanUtils.copyProperties(columnDto, column);
                    column.setSourceId(source.getId());
                    column.setSourceName(source.getName());
                    column.setDatabaseName(databaseName);
                    column.setTableId(table.getId());
                    column.setTableName(table.getTableName());
                    column.setCreateBy(source.getCreateBy());
                    column.setCreateTime(LocalDateTime.now());

                    allColumnList.add(column);
                    columnList.add(column);
                }
                columnMapper.insertList(columnList);
            }
        }

        log.info(JSONObject.toJSONString(allTableList));
        log.info(JSONObject.toJSONString(allColumnList));
        return true;
    }

}
